package top.iszsq.magic_api.Interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.model.ApiInfo;
import org.ssssssss.magicapi.model.JsonBean;
import org.ssssssss.magicapi.model.Options;
import org.ssssssss.magicapi.model.RequestEntity;
import org.ssssssss.script.MagicScriptContext;
import top.iszsq.base.enums.RenderEnums;
import top.iszsq.system.entity.SysUser;
import top.iszsq.utils.AuthUtils;
import top.iszsq.utils.RedisUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * magic-api 接口鉴权 拦截器
 * @author zsq
 * @date 2021/12/2 11:44
 **/
@Component
public class ApiAuthInterceptor implements RequestInterceptor {

    public static final Logger log = LoggerFactory.getLogger(ApiAuthInterceptor.class);

    @Resource
    private ThreadPoolTaskExecutor executor;

    @Resource
    private AuthUtils authUtils;

    @Resource
    private RedisUtils redisUtils;

    /**
     * 接口请求之前
     * @param info	接口信息
     * @param context	脚本变量信息
     */
    @Override
    public Object preHandle(ApiInfo info, MagicScriptContext context, HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.debug("---进入鉴权拦截器---请求接口：{}({})", info.getName(), info.getPath());
        // 记录接口请求次数
        executor.execute(new Runnable() {
            @Override
            public void run() {
                String requestURI = request.getRequestURI();
                double apiRequestCount = redisUtils.zincrby("apiRequestCount", 1.0, requestURI);
                log.debug("requestURI: {}， 访问次数：{}", requestURI, apiRequestCount);
            }
        });


        // 如果接口选项配置了不需要登录
        if ("true".equals(info.getOptionValue(Options.ANONYMOUS))) {
            return null;
        }

        // 检查是否已经登录
        SysUser sysUser = authUtils.currentUser();
        if (sysUser == null) {
            return new JsonBean<>(RenderEnums.needLogin.getCode(), RenderEnums.needLogin.getName());
        }


        return null;
    }

    /**
     * 接口执行完成后
     * @param requestEntity
     * @param returnValue
     * @param throwable
     */
    @Override
    public void afterCompletion(RequestEntity requestEntity, Object returnValue, Throwable throwable) {
        ApiInfo info = requestEntity.getApiInfo();
        Long requestTime = requestEntity.getRequestTime();
        long currentTimeMillis = System.currentTimeMillis();
        long executeTime = (currentTimeMillis - requestTime);

        String path = info.getPath();
        String name = info.getName();
        log.debug("---鉴权拦截器---接口执行完成后： {}({})", name, path);
        log.info("执行耗时ms：{}", executeTime);
    }

}
